package ants_pool

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/panjf2000/ants/v2"
)

// 注意看test代码样例

func getPool() {
	// 使用选项模式配置
	p, _ := ants.NewPool(1000,
		ants.WithNonblocking(true),              // 非阻塞模式
		ants.WithExpiryDuration(10*time.Second), // 空闲goroutine存活时间
		ants.WithPreAlloc(true),                 // 预分配
		ants.WithMaxBlockingTasks(100),          // 最大阻塞任务数
		ants.WithPanicHandler(func(p interface{}) {
			fmt.Printf("panic: %v\n", p) // panic处理器
		}),
		//ants.WithLogger(ants.DefaultLogger()), // 日志
	)
	defer p.Release()
}

func ExecWithParam() {
	var wg sync.WaitGroup

	p, _ := ants.NewPoolWithFunc(10, func(i interface{}) {
		fmt.Printf("参数：d% \n", i)
		wg.Done()
	})
	defer p.Release()

	// 提交带参数的任务
	for i := 0; i < 100; i++ {
		wg.Add(1)
		_ = p.Invoke(int32(i))
	}

	wg.Wait()
	fmt.Printf("running goroutines: %d\n", p.Running())
}

func Simple() {
	// 创建自定义配置的池
	options := ants.Options{
		ExpiryDuration:   10 * time.Second, // goroutine 过期时间
		PreAlloc:         false,            // 是否预分配
		MaxBlockingTasks: 100,              // 最大阻塞任务数
		Nonblocking:      false,            // 是否非阻塞
		PanicHandler: func(interface{}) {
			fmt.Println("捕获到 panic")
		},
	}

	p, _ := ants.NewPool(10, ants.WithOptions(options))
	defer p.Release()

	var wg sync.WaitGroup

	for i := 0; i < 20; i++ {
		wg.Add(1)
		i := i
		err := p.Submit(func() {
			defer wg.Done()
			if i == 5 {
				panic("测试 panic")
			}
			fmt.Printf("任务 %d 在 goroutine 中执行\n", i)
			time.Sleep(500 * time.Millisecond)
		})

		if err != nil {
			fmt.Printf("提交任务失败: %v\n", err)
			wg.Done()
		}
	}

	wg.Wait()

	fmt.Printf("池容量: %d\n", p.Cap())
	fmt.Printf("运行中的 goroutines: %d\n", p.Running())
	fmt.Printf("已完成的任务数: %d\n", p.Running())
}

func GoAnt(wg sync.WaitGroup, p *ants.Pool, f func()) {
	wg.Add(1)
	p.Submit(func() {
		defer wg.Done()
		f()
	})
}

func WaitG() {
	// 创建自定义配置的池
	options := ants.Options{
		ExpiryDuration:   10 * time.Second, // goroutine 过期时间
		PreAlloc:         false,            // 是否预分配
		MaxBlockingTasks: 100,              // 最大阻塞任务数
		Nonblocking:      false,            // 是否非阻塞
		PanicHandler: func(interface{}) {
			fmt.Println("捕获到 panic")
		},
	}

	p, _ := ants.NewPool(10, ants.WithOptions(options))
	defer p.Release()

	var wg sync.WaitGroup

	GoAnt(wg, p, func() {
		log.Println("坦克里没有后视镜的")
	})

	GoAnt(wg, p, func() {
		log.Println("枪炮是不长眼的")
	})

	GoAnt(wg, p, func() {
		log.Println("跟黑哥们的语言是不通的")
	})

	wg.Wait()
	log.Println("所有Goroutine完成")
}

type TaskResult struct {
	Output int
	Error  error
}

type TaskParam struct {
	I int
	f func(int) (int, error)
}

func PoolWithFunc() {
	// 创建自定义配置的池
	options := ants.Options{
		ExpiryDuration:   10 * time.Second, // goroutine 过期时间
		PreAlloc:         false,            // 是否预分配
		MaxBlockingTasks: 100,              // 最大阻塞任务数
		Nonblocking:      false,            // 是否非阻塞
		PanicHandler: func(interface{}) {
			fmt.Println("捕获到 panic")
		},
	}

	results := make(chan TaskResult, 10)
	var wg sync.WaitGroup
	// 处理结果的函数
	pf := func(data interface{}) {
		defer wg.Done()

		param := data.(TaskParam)
		r, err := param.f(param.I)

		results <- TaskResult{
			Output: r,
			Error:  err,
		}
	}

	// 创建带函数的池
	pool, err := ants.NewPoolWithFunc(10, pf, ants.WithOptions(options))
	if err != nil {
		panic(err)
	}
	defer pool.Release()

	// 提交任务
	for i := 1; i <= 10; i++ {
		wg.Add(1)
		err := pool.Invoke(TaskParam{I: i, f: func(ii int) (int, error) {
			fmt.Printf("-----执行业务逻辑--------")
			return ii, nil
		}})
		if err != nil {
			fmt.Printf("Invoke task failed: %v\n", err)
			wg.Done()
		}
	}

	// 等待所有任务完成
	wg.Wait()
	close(results)

	// 处理结果
	for result := range results {
		fmt.Printf("Input: %v, Output: %d\n", result.Error, result.Output)
	}

}

func generateSecureToken() (string, error) {
	b := make([]byte, 32)
	if _, err := rand.Read(b); err != nil {
		return "", err
	}
	return hex.EncodeToString(b), nil
}
